package com.example.venue_reservation_service;



import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.Duration;

// 定义预约类
class Reservation {
    private int reservationId;
    private int userId;
    private int venueId;
    private LocalTime startTime;
    private LocalTime endTime;
    private LocalDate reservationDate;

    public Reservation(int reservationId, int userId, int venueId, LocalTime startTime, LocalTime endTime, LocalDate reservationDate) {
        this.reservationId = reservationId;
        this.userId = userId;
        this.venueId = venueId;
        this.startTime = startTime;
        this.endTime = endTime;
        this.reservationDate = reservationDate;
    }

    public int getUserId() {
        return userId;
    }

    public int getVenueId() {
        return venueId;
    }

    public LocalTime getStartTime() {
        return startTime;
    }

    public LocalTime getEndTime() {
        return endTime;
    }

    public LocalDate getReservationDate() {
        return reservationDate;
    }

    public DayOfWeek getDayOfWeek() {
        return reservationDate.getDayOfWeek();
    }

    public long getDurationHours() {
        return Duration.between(startTime, endTime).toHours();
    }
}
//1
// 定义场地推荐类
class VenueRecommender {
    private List<Reservation> reservations;

    public VenueRecommender(List<Reservation> reservations) {
        this.reservations = reservations;
    }

    // 推荐用户未来最可能预约的场地和时间段
    public Map<String, Object> recommendMostLikelyVenueAndTimePeriod(int targetUserId) {
        // 用于存储每个场地的预约次数
        Map<Integer, Integer> venueCountMap = new HashMap<>();
        // 用于存储每个场地最近一次的预约日期
        Map<Integer, LocalDate> venueLastDateMap = new HashMap<>();
        // 用于统计用户在一周各天的预约次数
        Map<DayOfWeek, Integer> dayOfWeekCountMap = new HashMap<>();
        // 用于统计用户在不同时间段的预约次数
        Map<LocalTime, Integer> timeSlotCountMap = new HashMap<>();
        // 用于统计不同时长的预约次数
        Map<Long, Integer> durationCountMap = new HashMap<>();

        for (Reservation reservation : reservations) {
            if (reservation.getUserId() == targetUserId) {
                int venueId = reservation.getVenueId();
                // 更新场地的预约次数
                venueCountMap.put(venueId, venueCountMap.getOrDefault(venueId, 0) + 1);
                // 更新场地最近一次的预约日期
                LocalDate currentDate = reservation.getReservationDate();
                if (!venueLastDateMap.containsKey(venueId) || currentDate.isAfter(venueLastDateMap.get(venueId))) {
                    venueLastDateMap.put(venueId, currentDate);
                }
                // 更新一周各天的预约次数
                DayOfWeek dayOfWeek = reservation.getDayOfWeek();
                dayOfWeekCountMap.put(dayOfWeek, dayOfWeekCountMap.getOrDefault(dayOfWeek, 0) + 1);
                // 更新不同时间段的预约次数
                LocalTime startTime = reservation.getStartTime();
                timeSlotCountMap.put(startTime, timeSlotCountMap.getOrDefault(startTime, 0) + 1);
                // 更新不同时长的预约次数
                long duration = reservation.getDurationHours();
                durationCountMap.put(duration, durationCountMap.getOrDefault(duration, 0) + 1);
            }
        }

        int mostLikelyVenue = -1;
        int maxCount = -1;
        LocalDate latestDate = LocalDate.MIN;

        for (Map.Entry<Integer, Integer> entry : venueCountMap.entrySet()) {
            int venueId = entry.getKey();
            int count = entry.getValue();
            LocalDate lastDate = venueLastDateMap.get(venueId);

            if (count > maxCount || (count == maxCount && lastDate.isAfter(latestDate))) {
                mostLikelyVenue = venueId;
                maxCount = count;
                latestDate = lastDate;
            }
        }

        // 找出用户预约最多的星期几
        DayOfWeek mostLikelyDay = null;
        int maxDayCount = -1;
        for (Map.Entry<DayOfWeek, Integer> entry : dayOfWeekCountMap.entrySet()) {
            DayOfWeek day = entry.getKey();
            int dayCount = entry.getValue();
            if (dayCount > maxDayCount) {
                mostLikelyDay = day;
                maxDayCount = dayCount;
            }
        }

        // 找出用户预约最多的时间段
        LocalTime mostLikelyStartTime = null;
        int maxTimeSlotCount = -1;
        for (Map.Entry<LocalTime, Integer> entry : timeSlotCountMap.entrySet()) {
            LocalTime startTime = entry.getKey();
            int timeSlotCount = entry.getValue();
            if (timeSlotCount > maxTimeSlotCount) {
                mostLikelyStartTime = startTime;
                maxTimeSlotCount = timeSlotCount;
            }
        }

        // 找出用户最常见的预约时长
        long mostLikelyDuration = -1;
        int maxDurationCount = -1;
        for (Map.Entry<Long, Integer> entry : durationCountMap.entrySet()) {
            long duration = entry.getKey();
            int durationCount = entry.getValue();
            if (durationCount > maxDurationCount) {
                mostLikelyDuration = duration;
                maxDurationCount = durationCount;
            }
        }

        // 根据当前日期找到下一个最可能预约的日期
        LocalDate now = LocalDate.now();
        LocalDate nextMostLikelyDate = now;
        while (nextMostLikelyDate.getDayOfWeek()!= mostLikelyDay || nextMostLikelyDate.isBefore(now)) {
            nextMostLikelyDate = nextMostLikelyDate.plusDays(1);
        }

        LocalTime mostLikelyEndTime = mostLikelyStartTime.plusHours(mostLikelyDuration);

        Map<String, Object> result = new HashMap<>();
        result.put("venueId", mostLikelyVenue);
        result.put("date", nextMostLikelyDate);
        result.put("startTime", mostLikelyStartTime);
        result.put("endTime", mostLikelyEndTime);

        return result;
    }
}

public class tuijian {
    public static void main(String[] args) {
        List<Reservation> reservations = new ArrayList<>();
        try {
            FileInputStream file = new FileInputStream(new File("F:\\WeChat Files\\wxid_px2vbvrm2uy711\\FileStorage\\File\\2025-05\\reservation-ff7a1.xlsx"));
            XSSFWorkbook workbook = new XSSFWorkbook(file);
            XSSFSheet sheet = workbook.getSheet("模板");

            for (Row row : sheet) {
                if (row.getRowNum() == 0) {
                    continue; // 跳过表头行
                }
                int reservationId = (int) row.getCell(0).getNumericCellValue();
                int userId = (int) row.getCell(1).getNumericCellValue();
                int venueId = (int) row.getCell(2).getNumericCellValue();
                String startTimeStr = row.getCell(3).getStringCellValue();
                String endTimeStr = row.getCell(4).getStringCellValue();
                // 去除日期字符串两端的空白字符
                String reservationDateStr = row.getCell(5).getStringCellValue().trim();

                LocalTime startTime = LocalTime.parse(startTimeStr);
                LocalTime endTime = LocalTime.parse(endTimeStr);
                LocalDate reservationDate = LocalDate.parse(reservationDateStr);

                reservations.add(new Reservation(reservationId, userId, venueId, startTime, endTime, reservationDate));
            }

            workbook.close();
            file.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        VenueRecommender recommender = new VenueRecommender(reservations);
        int targetUserId = 16;
        Map<String, Object> recommendedResult = recommender.recommendMostLikelyVenueAndTimePeriod(targetUserId);

        System.out.println("用户 " + targetUserId + " 未来最可能预约的场地编号: " + recommendedResult.get("venueId"));
        System.out.println("未来最可能预约的日期: " + recommendedResult.get("date"));
        System.out.println("未来最可能预约的开始时间: " + recommendedResult.get("startTime"));
        System.out.println("未来最可能预约的结束时间: " + recommendedResult.get("endTime"));
    }
}